package net.nm.skype;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import thinktank.twitter.Twitter;

import com.skype.Call;
import com.skype.CallListener;
import com.skype.CallPartner;
import com.skype.CallStatusChangedListener;
import com.skype.Chat;
import com.skype.ChatMessage;
import com.skype.ChatMessageListener;
import com.skype.SkypeException;
import com.skype.User;
import com.skype.Call.Status;
import com.skype.connector.ConnectorListener;
import com.skype.connector.ConnectorMessageEvent;
import com.skype.connector.ConnectorStatusEvent;

/**
 * Skype Activity Recorder allows to capture the chat/call activities
 * and send it to a twitter account
 * 
 * @since 6 Fev 2007
 * @author Nicolas Maisonneuve
 * 
 */
public class ActivityHandler implements ConnectorListener, ChatMessageListener,
		CallListener {

	Log log = LogFactory.getLog(ActivityHandler.class);
	
	public boolean started = true;

	/**
	 * Skype Account allowing to capture the activity
	 */
	public String skype_accountID;
	public String twitter_accountID;
	Twitter twitterAPI;
	GraphicHandler graphics;
	Date lastupdate;
	
	public ActivityHandler() {
		graphics = new GraphicHandler();
		graphics.setController(this);

	}

	public void setSkypeAccount(String skypeAccountID) {
		this.skype_accountID = skypeAccountID;

	}

	public void setTwitterAccount(String username, String password) {
		this.twitter_accountID = username;
		twitterAPI = new Twitter(username, password);
	}
	
	public void callMaked(Call call) throws SkypeException {
		__call(call);
	}

	public void callReceived(Call call) throws SkypeException {
		__call(call);
	}

	public void chatMessageSent(ChatMessage msg) throws SkypeException {
		__chat(msg);
	}

	public void chatMessageReceived(ChatMessage msg) throws SkypeException {
		__chat(msg);
	}

	public void messageSent(ConnectorMessageEvent arg0) {
	}

	public void statusChanged(ConnectorStatusEvent arg0) {
	}

	public void messageReceived(ConnectorMessageEvent msgevent) {
		String msg = msgevent.getMessage();
		if (msg.startsWith("CONNSTATUS")) {
			msg(msg);
		}
		if (msg.startsWith("PROFILE MOOD_TEXT")) {
			msg(msg);
		}
		// System.out.println(msg);
	}


	protected void __call(final Call call) {
		call.addCallStatusChangedListener(new CallStatusChangedListener() {
			@Override
			public void statusChanged(Status status) throws SkypeException {
				switch (status) {
				case INPROGRESS:
					msg("is talking with " + to_twitter(call) + "on Skype");
					break;
				case FINISHED:
				case CANCELLED:
					msg("has finished talking with " + to_twitter(call)
							+ "on Skype (" + (call.getDuration() / 60)
							+ " minute(s))");
				}
			}
		});
	}

	protected void __chat(ChatMessage msg) throws SkypeException {
		Set<User> members = new HashSet(Arrays.asList(msg.getChat()
				.getAllMembers()));
		members.remove(skype_accountID);
		switch (msg.getType()) {

		case SAID:
			/*
			 * msg("is chatting with " + to_twitter(members) + "on Skype
			 * (chat_id: " + get_chat_id(msg) + ")");
			 */
			break;
		case CREATEDCHATWITH:
			msg("is chatting with " + to_twitter(members)
					+ "on Skype (chat_id:" + get_chat_id(msg) + ")");
			break;
		case ADDEDMEMBERS:
		case SAWMEMBERS:
			msg("is chatting now with " + to_twitter(members)
					+ "on Skype (chat_id:" + get_chat_id(msg) + ")");
			break;
		case LEFT:
			msg("has finished chatting with " + to_twitter(members)
					+ "on Skype (chat_id:" + get_chat_id(msg) + ")");
		}
	}

	public void init() {
		try {
			graphics.init();
		} catch (Exception e) {
			log.error("graphics error",e);
		}
	}

	protected void msg(String msg) {
		
		if (!started) return;
		
		Date now= new Date();
		if ((lastupdate==null) || (((now.getTime()-lastupdate.getTime())/(1000*3600))>3)){
					graphics.notifyInfo("your skype activiy is recorded");
		}
		lastupdate=now;
		
		log.info(msg);
		
		if (twitterAPI != null)
			twitterAPI.setStatus(msg);
	}

	private String to_twitter(Set<User> users) {
		String r = "";
		for (User user : users) {
			if (user.getId().equals(skype_accountID))
				users.remove(user);
			else
				r += "@" + user.getId() + " ";
		}
		return r;
	}

	private String get_chat_id(ChatMessage msg) throws SkypeException {
		Chat chat = msg.getChat();
		String chatID = chat.getId().substring(chat.getId().indexOf(";") + 1);
		return chatID;
	}
	
	private String to_twitter(Call call) throws SkypeException {

		int count = call.getParticipantsCount();
		if (count == 0) {
			return "@" + call.getPartnerId() + " ";
		}
		String r = "";
		for (int i = 0; i < count; i++) {
			CallPartner callPartner = call.getParticipant(i);
			if (!callPartner.getPartner().equals(skype_accountID))
				r += "@" + callPartner.getPartner() + " ";
		}
		return r;
	}
}
